package com.psp.web.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Objects;
import com.northend.util.AppTextUtil;
import com.northend.util.StringUtil;
import com.psp.web.cache.dao.AreaCache;
import com.psp.web.controller.res.bean.RAddressDetailBean;
import com.psp.web.controller.res.bean.RAddressListBean;
import com.psp.web.controller.res.bean.RAreaListBean;
import com.psp.web.model.AddressBean;
import com.psp.web.model.AreaBean;
import com.psp.web.model.extend.AddressJson;
import com.psp.web.persist.dao.AddressDao;
import com.psp.web.persist.dao.AreaDAO;
import com.psp.web.service.AddressService;
import com.psp.web.service.exception.ServiceException;

@Service
public class AddressServiceImpl implements AddressService {

	@Autowired
	AddressDao addressImpl;

	@Autowired
	AreaDAO areaImpl;

	@Autowired
	AreaCache areaCacheImpl;

	@Override
	public RAddressDetailBean getDetail(String aid) {
		RAddressDetailBean result = null;
		AddressBean bean = addressImpl.selectById(aid);
		if (bean != null) {
			result = new RAddressDetailBean();
			result.setAid(bean.getAid());
			result.setType(bean.getType());
			result.setAddressee(bean.getName());
			result.setPhone(bean.getPhone());
			result.setPcds(bean.getPcds());
			AddressJson address = JSON.parseObject(bean.getDetail(), AddressJson.class);
			if (address != null) {
				result.setDetail(address.getDetail());
			}
			result.setIsDefault(bean.getIsDefault() != null ? bean.getIsDefault() == 1 ? true : false : false);
		}
		return result;
	}

	@Override
	public PageResult<RAddressListBean> getList(int page, int pageSize, String uid, Integer type) {
		PageResult<RAddressListBean> result = new PageResult<RAddressListBean>();
		int count = addressImpl.selectCount(uid, type);
		List<AddressBean> resList = addressImpl.selectList(page, pageSize, uid, type);
		List<RAddressListBean> resData = new ArrayList<>();
		if (resList != null && resList.size() > 0) {
			for (AddressBean bean : resList) {
				RAddressListBean rb = new RAddressListBean();
				AddressJson address = JSON.parseObject(bean.getDetail(), AddressJson.class);
				rb.setAid(bean.getAid());
				rb.setAddressee(bean.getName());
				rb.setPhone(bean.getPhone());
				rb.setPcds(bean.getPcds());
				if (address != null) {
					rb.setProvince(address.getProvince());
					rb.setCity(address.getCity());
					rb.setDistrict(address.getDistrict());
					rb.setDetail(address.getDetail());
				}
				rb.setIsDefault(bean.getIsDefault() != null ? bean.getIsDefault() == 1 ? true : false : false);
				resData.add(rb);
			}
		}
		result.setCount(count);
		result.setData(resData);
		return result;

	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean save(String uid, String aid, String addressee, String phone, String detail, String pcds,
			Integer type) throws ServiceException {
		boolean flag = false;
		boolean isNew = StringUtil.isEmpty(aid);

		if (StringUtil.isEmpty(uid)) {
			throw new ServiceException("token_fail");
		}

		AddressBean bean = new AddressBean();
		bean.setAid(aid);
		bean.setUid(uid);
		bean.setName(addressee);
		bean.setPhone(phone);
		bean.setType(type);
		bean.setPcds(pcds);
		List<String> pcdList = JSON.parseArray(pcds, String.class);
		List<AreaBean> list = areaImpl.selectListByIds(pcdList);
		AddressJson address = new AddressJson();
		if (list != null && list.size() > 0) {
			for (AreaBean area : list) {
				if (area.getLevel() == 1) {
					address.setProvince(area.getName());
				} else if (area.getLevel() == 2) {
					address.setCity(area.getName());
				} else if (area.getLevel() == 3) {
					address.setDistrict(area.getName());
				}
			}
		}
		address.setDetail(detail);
		bean.setDetail(JSON.toJSONString(address));

		if (isNew) {
			bean.setAid(AppTextUtil.getPrimaryKey());
			bean.setCreateDate(new Date());
			flag = addressImpl.insert(bean) > 0;
		} else {
			AddressBean oldAddress = addressImpl.selectById(aid);
			if (oldAddress == null) {
				throw new ServiceException("object_is_not_exist", "用户地址");
			}
			if (!Objects.equal(oldAddress.getUid(), uid)) {
				throw new ServiceException("object_is_not_exist", "用户地址");
			}
			flag = addressImpl.update(bean) > 0;
		}

		if (!flag) {
			throw new ServiceException("fail");
		}
		return flag;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean deleteById(String uid, String aid) throws ServiceException {
		boolean flag = false;
		if (StringUtil.isEmpty(uid)) {
			throw new ServiceException("token_fail");
		}
		flag = addressImpl.deleteById(aid, uid) > 0;
		if (!flag) {
			throw new ServiceException("fail");
		}
		return flag;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean setDefault(String uid, String aid) throws ServiceException {
		boolean flag = false;
		if (StringUtil.isEmpty(uid)) {
			throw new ServiceException("token_fail");
		}
		AddressBean bean = addressImpl.selectById(aid);
		if (bean == null) {
			throw new ServiceException("object_is_not_exist", "用户地址");
		}
		if (!Objects.equal(bean.getUid(), uid)) {
			throw new ServiceException("object_is_not_exist", "用户地址");
		}
		if (bean.getIsDefault() != null && bean.getIsDefault() == 1) {// 已经设置过默认
			return true;
		}

		if (bean.getType() != null) {
			int type = bean.getType();
			// 先更新非默认
			flag = addressImpl.updateDefault(uid, type, 0) > 0;

			// 更新默认
			AddressBean defaultBean = new AddressBean();
			defaultBean.setAid(aid);
			defaultBean.setIsDefault(1);
			flag = addressImpl.update(defaultBean) > 0;
			if (!flag) {
				throw new ServiceException("fail");
			}
		}
		return flag;
	}

	/**
	 * 获取 根据获得子区域 当id 为空的时候，返回省级列表
	 */
	@Override
	public PageResult<RAreaListBean> getAreas(String id) {
		PageResult<RAreaListBean> result = new PageResult<>();
		List<RAreaListBean> resData = new ArrayList<>();

		if (StringUtil.isEmpty(id)) {
			id = "province";
		}

		List<AreaBean> reslist;
		String res = areaCacheImpl.getSubAreaById(id);
		if (!StringUtil.isEmpty(res)) {
			reslist = JSON.parseArray(res, AreaBean.class);
		} else {
			AreaBean areaBean = areaImpl.selectById(id);
			if (areaBean != null) {
				reslist = areaImpl.selectListByPid(areaBean.getId());
			} else {
				reslist = areaImpl.selectListByPid("");
			}
			Object resObj = JSON.toJSON(reslist);
			if (resObj != null) {
				areaCacheImpl.setSubAreaById(id, resObj.toString());
			}
		}

		int count = 0;
		if (reslist != null && reslist.size() > 0) {
			for (AreaBean bean : reslist) {
				RAreaListBean rb = new RAreaListBean();
				rb.setLabel(bean.getName());
				rb.setValue(bean.getId());
				resData.add(rb);
			}
			count = reslist.size();
		}
		result.setData(resData);
		result.setCount(count);
		return result;
	}

	@Override
	public PageResult<RAreaListBean> getAreas() {
		PageResult<RAreaListBean> result = new PageResult<>();

		String areapcd = areaCacheImpl.getAreaPCD();
		List<RAreaListBean> resultList;
		if (!StringUtil.isEmpty(areapcd)) {
			resultList = JSON.parseArray(areapcd, RAreaListBean.class);
		} else {
			List<AreaBean> lists = areaImpl.selectListByPCD();
			resultList = new ArrayList<>();
			if (lists != null && lists.size() > 0) {
				for (AreaBean pArea : lists) {
					if (pArea.getSubArea() != null && pArea.getSubArea().size() > 0) {
						RAreaListBean pAreaList = new RAreaListBean();
						pAreaList.setLabel(pArea.getName());
						pAreaList.setValue(pArea.getId());
						List<RAreaListBean> pSubList = new ArrayList<>();
						for (AreaBean cArea : pArea.getSubArea()) {
							RAreaListBean cArealist = new RAreaListBean();
							cArealist.setLabel(cArea.getName());
							cArealist.setValue(cArea.getId());
							pSubList.add(cArealist);
							if (cArea.getSubArea() != null && cArea.getSubArea().size() > 0) {
								List<RAreaListBean> cSubList = new ArrayList<>();
								cArealist.setChildren(cSubList);
								for (AreaBean dArea : cArea.getSubArea()) {
									RAreaListBean dAreaList = new RAreaListBean();
									dAreaList.setLabel(dArea.getName());
									dAreaList.setValue(dArea.getId());
									cSubList.add(dAreaList);
								}
							}
						}
						pAreaList.setChildren(pSubList);
						resultList.add(pAreaList);
					}
				}
				areaCacheImpl.setAreaPCD(JSON.toJSON(resultList).toString());
			}
		}

		result.setData(resultList);
		return result;
	}

}
